package http

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"xrt/components/http/session/sess"
	"xrt/components/http/static"
	"xrt/interfaces"
	"xrt/utils/file/log"
	"xrt/utils/web"
)

type XHttp struct {
	Writer  http.ResponseWriter
	Reader  *http.Request
	Path    string
	Pattern []string
	Method  string
	Session session.Store
	status  int
	sync    *xHttpLayer
	async   interfaces.IfAsync
}

type basePage struct {
	Title string
}

func (h *XHttp) toNotFound() {
	h.SetRespStatus(http.StatusNotFound)
	h.sync.patternMap[ERR404]["Default"](h)
}

func (h *XHttp) ParseBaseTemplate(title string, content string) {
	t, _ := template.New("BaseHtml").Parse(static.XRTBasePageTemplate)
	t.Parse(`{{define "content"}} ` + content + ` {{end}}`)
	t.Execute(h.Writer, basePage{Title: title})
}

func (h *XHttp) GetParams() map[string]string {
	return web.GetParams(h.Reader)
}

func (h *XHttp) SetRespStatus(status int) {
	h.status = status
	h.Writer.WriteHeader(status)
}

func (h *XHttp) GetRespStatus() int {
	return h.status
}

func (h *XHttp) RedirectTo(url string, absolute bool) {
	switch url {
	case ERR404:
		h.toNotFound()
	default:
		log.Debugf("Redirect to Url: [%s].", url)
		http.Redirect(h.Writer, h.Reader, url, http.StatusFound)
	}
}

func (h *XHttp) WriteString(rtString string) {
	fmt.Fprint(h.Writer, rtString)
}

func (h *XHttp) WriteStringf(tStr string, params ...interface{}) {
	fmt.Fprintf(h.Writer, tStr, params...)
}

func (h *XHttp) WriteToJson(strMap map[string]string) {
	if rtJson, err := json.Marshal(strMap); err != nil {
		fmt.Fprintf(h.Writer, "%s", err.Error())
	} else {
		fmt.Fprintf(h.Writer, "%s", rtJson)
	}
}

func (h *XHttp) WriteFile(filePath string) {
	if fileContent, err := ioutil.ReadFile(filePath); err != nil {
		fmt.Fprint(h.Writer, fileContent)
	}
}

func (h *XHttp) WriteFileContent(fileContent []byte) {
	fmt.Fprint(h.Writer, fileContent)
}

func (h *XHttp) SendAsyncMessage(message string) {
	h.async.Push(message)
}
